package cac.fenjian.resource.wmsdeliverplan.rest;

import cac.common.CallInterFace.service.CallInterfaceService;
import cac.common.CreatMsgId;
import cac.common.R;
import cac.fenjian.resource.MsWpTool.dto.MsWpToolBasicDTO;
import cac.fenjian.resource.TsUser.dto.TsUserDTO;
import cac.fenjian.resource.WmsDeliverPlan.dto.WmsDeliverPlanDTO;
import cac.fenjian.resource.materialreceipt.util.MaterialReceiptSyn;
import cac.fenjian.resource.partreceivesearch.service.PartReceiveService;
import cac.fenjian.resource.tsuser.service.TsUserServiceImpl;
import cac.fenjian.resource.wmsdeliverplan.dao.WmsDeliverPlanDao;
import cac.fenjian.resource.wmsdeliverplan.service.WmsDeliverPlanService;
import cac.gkinterface.service.WorkService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cac.dme.adapter.rest.msg.PageParameter;
import com.cac.dme.adapter.rest.msg.QueryReqBean;
import com.cac.dme.adapter.rest.msg.QueryRespBean;
import com.cac.dme.adapter.rest.msg.ResponseMsg;
import com.cac.dme.adapter.utils.ContextCommonHolder;
import com.cac.dme.common.utils.JsonHelper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.cac.dme.adapter.utils.BusinessUtil.getSortExpColumnName;

/**
 * @program test-curd
 * @description 配送计划表接口
 * @author: LSL
 * @create: 2022-08-18-17-03
 **/
@RestController
@RequestMapping("/WmsDeliverPlan")
@Slf4j
public class WmsDeliverPlanRest {

    @Autowired
    private WmsDeliverPlanService wmsDeliverPlanService;
    @Autowired
    private CallInterfaceService callInterfaceService;
    @Autowired
    private TransactionDefinition transactionDefinition;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;
    @Autowired
    private WmsDeliverPlanDao wmsDeliverPlanDao;
    @Autowired
    private PartReceiveService partReceiveService;
    @Autowired
    private MaterialReceiptSyn materialReceiptSyn;
    @Autowired
    private TsUserServiceImpl tsUserService;
    @Autowired
    private Environment environment;
    @Autowired
    private WorkService workService;


    /**
     * 移交单信息查询
     *
     * @param map
     * @return
     */
    @PostMapping("/searchByPage")
    public ResponseMsg<QueryRespBean<WmsDeliverPlanDTO>> searchMsAccMatByPage(@RequestBody Map map) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ResponseMsg<QueryRespBean<WmsDeliverPlanDTO>> responseMsg = new ResponseMsg<>();
        String type = (String) map.get("funcType");
        log.info(type);
        String param = JSON.toJSONString(map.get("pageParameter"));
        PageParameter pageParameter = JSON.parseObject(param, PageParameter.class);
        String DTO = JSON.toJSONString(map.get("searchParams"));
        WmsDeliverPlanDTO searchParams = JSON.parseObject(DTO, WmsDeliverPlanDTO.class);
        String account = (String) request.getSession().getAttribute("account");
        if (Objects.isNull(account)) {
            log.info("session过期，请重新登陆");
            responseMsg.setErrorDesc("账户已过期，请重新登录").setRetCode("201");
            return responseMsg;
        } else if ("admin".equals(account)) {
            return responseMsg.setRetCode("201").setErrorDesc("管理员账号无法完成操作，请切换登录用户");
        }
        QueryReqBean<WmsDeliverPlanDTO> queryReqBean = new QueryReqBean<>();
        queryReqBean.setSearchParams(searchParams);
        queryReqBean.setPageParameter(pageParameter);

        if (StringUtils.hasText(queryReqBean.getSidx()) && StringUtils.hasText(queryReqBean.getSord())) {
            String sordExp = getSortExpColumnName(queryReqBean.getSidx(), queryReqBean.getSord(), MsWpToolBasicDTO.class);
            if (StringUtils.hasText(queryReqBean.getKeyWord())) {
                queryReqBean.setSortExp(sordExp);
            }
        }
        if (StringUtils.hasText(queryReqBean.getKeyWord())) {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            WmsDeliverPlanDTO searchKeyWordParam = JsonHelper.getInstance().readValue(queryReqBean.getKeyWord(), dateFormat, new TypeReference<WmsDeliverPlanDTO>() {
            });
            queryReqBean.setSearchParams(searchKeyWordParam);
        }
        String IP = null;

        if (request.getHeader("x-forwarded-for") == null) {
            IP = request.getRemoteAddr();
        } else {
            IP = request.getHeader("x-forwarded-for");
        }
        log.info("IP:" + IP);
        //2023-11-05 yebo 设置单位
        String shop = (String)tsUserService.getUserInfoByAccount(account).get("shop");
        QueryRespBean<WmsDeliverPlanDTO> result = wmsDeliverPlanService.searchWmsDeliverPlanDTOByPage(queryReqBean, queryReqBean.getSortExp(), type, IP,shop);
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    /**
     * yebo
     * 物料入库----待入库数据查询
     * **/
    @PostMapping("searchBeputMaterial")
    public PageInfo searchBeputMaterial(@RequestBody HashMap map){
        int pageNum = Integer.parseInt(map.get("currentPage").toString());
        int pageSize = Integer.parseInt(map.get("pageSize").toString());
        String ip = null;
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            ip = request.getHeader("x-forwarded-for");
        }
        return wmsDeliverPlanService.searchBeputMaterial(pageNum,pageSize,ip);
    }

    //标准件页面查询7-31
    @PostMapping("/searchPlanByItemTypeZ")
    public PageInfo searchPlanByItemTypeZ(@RequestBody HashMap map){
        int pageNum = Integer.parseInt(map.get("currentPage").toString());
        int pageSize = Integer.parseInt(map.get("pageSize").toString());
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String account = (String) request.getSession().getAttribute("account");
        if (Objects.isNull(account)) {
            log.info("session过期，请重新登陆");
            return null;
        } else if ("admin".equals(account)) {
            return null;
        }
        String shop = (String)tsUserService.getUserInfoByAccount(account).get("shop");
        return wmsDeliverPlanService.searchPlanByItemTypeZ(pageNum,pageSize,shop);
    }



    /**
     * 零件-成品接收 保存备注
     */
    @PostMapping("saveRemark")
    public ResponseMsg saveRemark(@RequestBody HashMap map) {
        ResponseMsg responseMsg = new ResponseMsg();
        List<HashMap> deliverys = (List<HashMap>) map.get("dliverys");
        String remark = (String) map.get("remark");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String userCode = (String) request.getSession().getAttribute("account");
        if (Objects.isNull(userCode)) {
            log.info("session过期，请重新登陆");
            responseMsg.setMessage("账户已过期，请重新登录").setRetCode("201");
            return responseMsg;
        } else if ("admin".equals(userCode)) {
            return responseMsg.setRetCode("201").setErrorDesc("管理员账号无法完成操作，请切换登录用户");
        }
        responseMsg = wmsDeliverPlanService.saveRemark(deliverys, remark);
        return responseMsg;
    }

    /**
     * 物料扫码移交接口
     *
     * @param map
     * @return
     */
    @PostMapping("/changeAccType")
    public ResponseMsg<String> changeTransferType(@RequestBody Map map) throws ParseException {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        //条码
        String barCode = (String) map.get("barcode");
        //扫码人工号
        String userCode = (String) map.get("userCode");
        //扫码物料类型
        String barcodeType = (String) map.get("barcodeType");//值为 CP,LJ,BJ
        //扫码
        String bzjCodeType = (String) map.get("bzjCodeType");//值为BZJCK   BZJCKAO

        //yebo 2023-08-18 新增校验扫码人工号是否正确
        responseMsg = wmsDeliverPlanService.searchWorkerCode(userCode);
        if("201".equals(responseMsg.getRetCode())){
            return responseMsg;
        }

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String userId = (String) request.getSession().getAttribute("account");
        String msgId = CreatMsgId.getMsgId();
        String IP = null;
        if (request.getHeader("x-forwarded-for") == null) {
            IP = request.getRemoteAddr();
        } else {
            IP = request.getHeader("x-forwarded-for");
        }
        if (Objects.isNull(userId)) {
            log.info("session过期，请重新登陆");
            responseMsg.setErrorDesc("账户已过期，请重新登录").setMessage("账户已过期，请重新登录").setRetCode("201");
            return responseMsg;
        } else if ("admin".equals(userId)) {
            return responseMsg.setRetCode("201").setErrorDesc("管理员账号无法完成操作，请切换登录用户").setMessage("管理员账号无法完成操作，请切换登录用户");
        }
        log.info("IP" + IP);
        //事务管理
        TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
        String shop = (String)tsUserService.getUserInfoByAccount(userId).get("shop");

        try {
            if ("LJ".equals(barcodeType)) {//零件
                //判断当前零件的条码对应的合格证号是否重复
                if(partReceiveService.queryPartHgzIsRepeat(barCode,shop)){
                    platformTransactionManager.rollback(transaction);
                    return responseMsg.setRetCode("201").setMessage(barCode+"条码合格证号存在重复，请确认交接单是否重复").setErrorDesc(barCode+"条码合格证号存在重复，请确认交接单是否重复");
                }
                responseMsg = wmsDeliverPlanService.changeMaterialSate(barCode, IP, userCode);
                if ("200".equals(responseMsg.getRetCode())) {
                    responseMsg.setRetCode("200").setMessage("操作成功！");
                    //2023-12-25 yebo 调整扫码移交，零件存在不同单位相同barcode的数据
                    //String parameters = wmsDeliverPlanService.scanDelivery(barCode, userCode, userId, IP, msgId, barcodeType, bzjCodeType);
                    List<String> parameters = wmsDeliverPlanService.scanDeliveryLjCp(barCode,userCode,IP,msgId,barcodeType);
                    for(String parameter : parameters){
                        String code = "sendBData";
                        String sendScenario = "零件移交";
                        String name = "两网传输-发送业务数据";
                        long beginTime = System.currentTimeMillis();
                        log.info("======开始时间=======" + beginTime);
                        log.info("2023-11-03 yebo 扫码移交更改为异步的方式  在materialreceipt包下面");
                        materialReceiptSyn.sendBData(code, name, parameter, sendScenario);
                        //callInterfaceService.sendBData(code, name, parameters, sendScenario);
                        long endTime = System.currentTimeMillis();
                        log.info("======消耗时间=======" + (endTime - beginTime) + "ms");
                    }
                }
            } else if ("CP".equals(barcodeType)) {//成品
                //判断是否存在该核格证号的成品
                responseMsg = wmsDeliverPlanService.changeMaterialSateCP(barCode, IP, userCode);
                if ("200".equals(responseMsg.getRetCode())) {
                    if (responseMsg.getMessage().length() > 10) {
                        responseMsg.setMessage(responseMsg.getMessage());
                    } else {
                        responseMsg.setRetCode("200").setMessage("操作成功！");
                    }
                  //  String parameters = wmsDeliverPlanService.scanDelivery(barCode, userCode, userId, IP, msgId, barcodeType, bzjCodeType);
                    List<String> parameters = wmsDeliverPlanService.scanDeliveryLjCp(barCode,userCode,IP,msgId,barcodeType);
                    for(String parameter : parameters){
                        String code = "sendBData";
                        String sendScenario = "零件移交";
                        String name = "两网传输-发送业务数据";
                        long beginTime = System.currentTimeMillis();
                        log.info("======开始时间=======" + beginTime);
                        log.info("2023-11-03 yebo 扫码移交更改为异步的方式  在materialreceipt包下面");
                        materialReceiptSyn.sendBData(code, name, parameter, sendScenario);
                        //callInterfaceService.sendBData(code, name, parameters, sendScenario);
                        long endTime = System.currentTimeMillis();
                        log.info("======消耗时间=======" + (endTime - beginTime) + "ms");
                    }
                }
            } else {//标件
                responseMsg = wmsDeliverPlanService.changeMaterialSateBJ(barCode, IP, userCode);
                if ("200".equals(responseMsg.getRetCode())) {
                    responseMsg.setRetCode("200").setMessage("操作成功！");
                    //yebo 2023-08-05标准件不针对某本ao，针对具体的某个物料来移交
                    //查询此AO下要移交的AO
                    bzjCodeType = "BZJCK";
                    List<String> barcodes = wmsDeliverPlanDao.queryBzjBarcode(barCode);
                    for(String barco : barcodes){
                        String msgIdnew = CreatMsgId.getMsgId();
                        String parameters = wmsDeliverPlanService.scanDelivery(barco, userCode, userId, IP, msgIdnew, barcodeType, bzjCodeType);
                        String code = "sendBData";
                        String sendScenario = "零件移交";
                        String name = "两网传输-发送业务数据";
                        long beginTime = System.currentTimeMillis();
                        log.info("======开始时间=======" + beginTime);
                        log.info("2023-11-03 yebo 扫码移交更改为异步的方式  在materialreceipt包下面");
                        materialReceiptSyn.sendBData(code, name, parameters, sendScenario);
                        //callInterfaceService.sendBData(code, name, parameters, sendScenario);
                        long endTime = System.currentTimeMillis();
                        log.info("======消耗时间=======" + (endTime - beginTime) + "ms");
                    }
                }
            }
            if ("201".equals(responseMsg.getRetCode())) {//判断当前交接单是已移交还是未上账
                int c = wmsDeliverPlanService.searchDeliveryPlanExists(barCode);
                if (c == 0) {
                    responseMsg.setRetCode("201").setMessage("条码号为：" + barCode + "未预上账！请确认").setErrorDesc("条码号为：" + barCode + "未预上账！请确认");
                } else {
                    responseMsg.setRetCode("201").setMessage("条码号为：" + barCode + "已经移交！").setErrorDesc("条码号为：" + barCode + "已经移交！");
                }
                //全部成功提交事务
                platformTransactionManager.rollback(transaction);
            } else {
                //全部成功提交事务
                platformTransactionManager.commit(transaction);
            }
        } catch (Exception e) {
            //有一个失败，回滚事务
            e.printStackTrace();
            platformTransactionManager.rollback(transaction);
            responseMsg.setMessage(e.getMessage()).setRetCode("201");
        } finally {
            return responseMsg;
        }
    }


    /**
     * 扫码退回接口
     *
     * @param map
     * @return
     */
    @PostMapping("/changeRetrunType")
    public ResponseMsg<String> changeRetrunType(@RequestBody Map map) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        String barcode = (String) map.get("barcode");
        String returnReason = (String) map.get("returnReason");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String userId = (String) request.getSession().getAttribute("account");
        String IP = null;
        if (request.getHeader("x-forwarded-for") == null) {
            IP = request.getRemoteAddr();
        } else {
            IP = request.getHeader("x-forwarded-for");
        }
        log.info("IP" + IP);
        if (Objects.isNull(userId)) {
            log.info("session过期，请重新登陆");
            responseMsg.setMessage("账户已过期，请重新登录").setRetCode("201");
            return responseMsg;
        } else if ("admin".equals(userId)) {
            return responseMsg.setRetCode("201").setErrorDesc("管理员账号无法完成操作，请切换登录用户");
        }
        String barcodeType = (String) map.get("barcodeType");
        String bzjCodeType = (String) map.get("bzjCodeType");

        String wmsDeliverPlanId = "";
        List<String> wmsDeliverPlanIds = new ArrayList<>();
        //扫码人工号
        String userCode = (String) map.get("userCode");

        //不是标准件，成品零件一次只有一个，直接退
        if (!"BJ".equals(barcodeType)) {
            //yebo 新增获取当前退回条码的主键
            wmsDeliverPlanId = wmsDeliverPlanService.getScanBarcodeWmsDeliverPlanId(barcode);
            if(Objects.isNull(wmsDeliverPlanId)){
                return responseMsg.setMessage("未发起协调或协调单未提交！").setRetCode("201");
            }
            //yebo 2023-04-06 判断是否发起协调,以及单位是否一致
            responseMsg = wmsDeliverPlanService.checkCoordinate(wmsDeliverPlanId, userCode, userId);
            if ("201".equals(responseMsg.getRetCode())) {
                return responseMsg;
            }
        } else {
            wmsDeliverPlanIds = wmsDeliverPlanDao.searchBzjWmsId(barcode);
        }

        //事务管理
        TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
        try {
            Integer isSucceed = 0;
            if (!"BJ".equals(barcodeType)) {
                isSucceed = wmsDeliverPlanService.changeReturnTypeLjCP(wmsDeliverPlanId, barcode, returnReason, userId, userCode);
            } else {
                isSucceed = wmsDeliverPlanService.changeReturnTypeBzj(wmsDeliverPlanIds, barcode, returnReason, userId, userCode);
            }

            log.info("isSucceed" + isSucceed);
            if (isSucceed != 0) {
                responseMsg.setRetCode("200").setMessage("退回成功");
                String parameters = "";
                if (!"BJ".equals(barcodeType)) {
                    //成品 零件扫退回传erp
                    parameters = wmsDeliverPlanService.scanBackCpLj(wmsDeliverPlanId, barcode, userId, IP, userCode,returnReason);
                }else {
                    //标准件扫退回传erp
                    parameters = wmsDeliverPlanService.scanBackBzj(barcode, userId, IP, userCode,bzjCodeType,returnReason);
                }
                String code = "sendBData";
                String name = "两网传输-发送业务数据";
                String sendScenario = "扫码退回";
                long beginTime = System.currentTimeMillis();
                log.info("======开始时间=======" + beginTime);
                callInterfaceService.sendBData(code, name, parameters, sendScenario);
                long endTime = System.currentTimeMillis();
                log.info("======消耗时间=======" + (endTime - beginTime) + "ms");
            } else responseMsg.setRetCode("201").setErrorDesc("退回失败！");
            //全部成功提交事务
            platformTransactionManager.commit(transaction);
        } catch (Exception e) {
            //有一个失败，回滚事务
            e.printStackTrace();
            platformTransactionManager.rollback(transaction);
            responseMsg.setMessage(e.getMessage()).setRetCode("201");
        } finally {
            return responseMsg;
        }
    }

    /**
     * 判断退回物料条码是否合规
     *
     * @param map
     * @return
     */
    @PostMapping("/barcodeIsExist")
    public ResponseMsg<String> barcodeIsExist(@RequestBody Map map) {
        String barcode = (String) map.get("barcode");
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        Map returnMap = wmsDeliverPlanService.isExist(barcode);
        if (returnMap.get("exist").equals("no")) {
            responseMsg.setRetCode("201");
            log.info("responseMsg.getRetCode():" + responseMsg.getRetCode());
            responseMsg.setMessage("该条码不是移交状态，请检查交接单状态！");
        } else {
            responseMsg.setRetCode("200");
            responseMsg.setMessage("条码存在且合规！");
        }
        log.info("responseMsg:" + responseMsg);
        return responseMsg;
    }


    /**
     * 移交条件查询
     *
     * @param
     * @return
     */
    @PostMapping("/searchByParams")
    public ResponseMsg<QueryRespBean<WmsDeliverPlanDTO>> searchParams(@RequestBody Map map) {
        ResponseMsg<QueryRespBean<WmsDeliverPlanDTO>> responseMsg = new ResponseMsg<>();
        log.info("MAP++++++++++++++++++++++:::" + map.toString());
        //操作类型
        String funcType = (String) map.get("funcType");
        //时间范围
        String startTimeParams = JSON.toJSONString(map.get("startTime"));
        String endTimeParams = JSON.toJSONString(map.get("endTime"));
        Date startTime = JSON.parseObject(startTimeParams, Date.class);
        Date endTime = JSON.parseObject(endTimeParams, Date.class);
        //分页
        String param = JSON.toJSONString(map.get("pageParameter"));
        PageParameter pageParameter = JSON.parseObject(param, PageParameter.class);
        String IP = null;
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (request.getHeader("x-forwarded-for") == null) {
            IP = request.getRemoteAddr();
        } else {
            IP = request.getHeader("x-forwarded-for");
        }
        log.info("IP" + IP);
        log.info("" + request.getSession().getAttribute("tsUser"));

        //查询条件
        String searchParamsParams = JSON.toJSONString(map.get("searchParams"));
        WmsDeliverPlanDTO searchParams = JSON.parseObject(searchParamsParams, WmsDeliverPlanDTO.class);

        QueryReqBean<WmsDeliverPlanDTO> queryReqBean = new QueryReqBean<>();
        queryReqBean.setSearchParams(searchParams);
        queryReqBean.setPageParameter(pageParameter);

        if (StringUtils.hasText(queryReqBean.getSidx()) && StringUtils.hasText(queryReqBean.getSord())) {
            String sordExp = getSortExpColumnName(queryReqBean.getSidx(), queryReqBean.getSord(), WmsDeliverPlanDTO.class);
            if (StringUtils.hasText(sordExp)) {
                queryReqBean.setSortExp(sordExp);
            }
        }
        if (StringUtils.hasText(queryReqBean.getKeyWord())) {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            WmsDeliverPlanDTO searchKeyWordParam = JsonHelper.getInstance().readValue(queryReqBean.getKeyWord(), dateFormat, new TypeReference<WmsDeliverPlanDTO>() {
            });
            queryReqBean.setSearchParams(searchKeyWordParam);
        }

        QueryRespBean<WmsDeliverPlanDTO> result = wmsDeliverPlanService.searchByParams(queryReqBean, ContextCommonHolder.getOrgId(), queryReqBean.getSortExp(), startTime, endTime, funcType);
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    //判断工人工号是否存在
    @PostMapping("/searchWorkerCode")
    public ResponseMsg searchWorkerCode(@RequestBody HashMap map) {
        ResponseMsg responseMsg = new ResponseMsg();
        String smPerson = map.get("smPerson").toString();
        responseMsg = wmsDeliverPlanService.searchWorkerCode(smPerson);
        return responseMsg;
    }

    //xiaojian 5-31 设置默认备注
    @PostMapping("/setDefaultNotes")
    public HashMap setDefaultNotes(@RequestBody HashMap map) {
        HashMap hashMap = new HashMap();
        wmsDeliverPlanDao.setDefaultNotes((String) map.get("itemCode"));
        hashMap.put("retCode", "200");
        hashMap.put("retMsg", wmsDeliverPlanDao.setDefaultNotes((String) map.get("itemCode")));
        return hashMap;
    }
}
